﻿#include "EditorObjectPropertyAbilityModel.h"

#include "Window/EditorWindowGroupModel.h"
#include "Scene/SceneNode.h"

#include "Property/NodePosition/EditorNodePositionPropertyModel.h"
#include "Property/NodeRotation/EditorNodeRotationPropertyModel.h"
#include "Property/NodeScale/EditorNodeScalePropertyModel.h"
#include "Property/Component/EditorComponentPropertyModel.h"
#include "Property/AddComponent/EditorAddComponentPropertyModel.h"

#include "Mesh/StaticMesh.h"
#include "Property/MeshMaterial/EditorMeshMaterialPropertyModel.h"
#include "Pages/Mesh/EditorMeshPageModel.h"

CString REditorObjectPropertyAbilityModel::GetName() const
{ 
    if(Object)
    {
        return U"属性:"+Object->GetNodeName();
    }
    return U"属性: 未选中对象"; 
}

void REditorObjectPropertyAbilityModel::FirstTimeInitializeObject()
{
    Super::FirstTimeInitializeObject();
 
    REditorWindowGroupModel::Get()->OnFocusedObjectChanged.BindScript(
        this
        ,&REditorObjectPropertyAbilityModel::OnFocusedObjectChanged);

    OnFocusedObjectChanged(REditorWindowGroupModel::Get()->GetFocusedObject());  
}

void REditorObjectPropertyAbilityModel::AddComponent(TSubclassOf<RSceneNodeComponent> InComponentClass)
{
    assert(Object &&Object->IsA<RSceneNode>());

    RSceneNodePtr Node=Object;
    auto NewComponent=Node->CreateAndAddComponent(InComponentClass);

    auto ComponentProperty=
        REditorComponentPropertyModel::Create(NewComponent,this);

    //the last property is AddComponentProperty
    //so insert before it
    Properties.Insert(Properties.Num()-1,ComponentProperty);

    OnPropertyListChanged.ExecuteIfBound();
}

void REditorObjectPropertyAbilityModel::RemoveComponent(TSharedObjectPtr<RSceneNodeComponent> InComponent)
{
    assert(Object &&Object->IsA<RSceneNode>());

    RSceneNodePtr Node=Object;
    Node->RemoveComponent(InComponent);

    for(int64_t i=0;i<Properties.Num();++i)
    {
        if(Properties[i]->IsA<REditorComponentPropertyModel>())
        {
            REditorComponentPropertyModelPtr ComponentProperty=Properties[i];
            if(ComponentProperty->Component==InComponent)
            {
                Properties.RemoveAt(i);
                break;
            }
        }
    }

    OnPropertyListChanged.ExecuteIfBound();
}

void REditorObjectPropertyAbilityModel::OnFocusedObjectChanged(TSharedObjectPtr<RObject> InObject)
{
    Object=InObject;
    UpdateProperties();
}

void REditorObjectPropertyAbilityModel::UpdateProperties()
{
    Properties.Clear();
    if(Object)
    {
        auto CurrentPage=REditorWindowGroupModel::Get()->GetFocusedPage();

        if(Object->IsA<RSceneNode>())
        {
            RSceneNodePtr Node=Object;
            auto PositionProperty=
                REditorNodePositionPropertyModel::Create(Node,this);
            Properties.Add(PositionProperty);

            auto RotationProperty=
                REditorNodeRotationPropertyModel::Create(Node,this);
            Properties.Add(RotationProperty);

            auto ScaleProperty=
                REditorNodeScalePropertyModel::Create(Node,this);
            Properties.Add(ScaleProperty);

            for(auto Component:Node->GetAllComponents())
            {
                auto ComponentProperty=
                    REditorComponentPropertyModel::Create(Component,this);
                Properties.Add(ComponentProperty);
            }

            auto AddComponentProperty=
                REditorAddComponentPropertyModel::Create(Node,this);
            Properties.Add(AddComponentProperty);

        }
        else if(CurrentPage->IsA<REditorMeshPageModel>())
        {
            auto MeshMaterialProperty=
                REditorMeshMaterialPropertyModel::Create(CurrentPage,this);
            Properties.Add(MeshMaterialProperty);
        }

    }

    OnPropertyListChanged.ExecuteIfBound();
}
